package com.apanal.qlife.sys.controller;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.apanal.qlife.advice.model.Advice;
import com.apanal.qlife.advice.service.SysAnnounceService;
import com.apanal.qlife.common.annotation.CurrentUser;
import com.apanal.qlife.common.constants.Constants;
import com.apanal.qlife.common.exception.OrgDisableException;
import com.apanal.qlife.common.factory.SpringContextHolder;
import com.apanal.qlife.common.jcaptcha.JCaptcha;
import com.apanal.qlife.common.page.Page;
import com.apanal.qlife.common.util.PropertieUtil;
import com.apanal.qlife.org.service.OrganizationService;
import com.apanal.qlife.sys.model.Resource;
import com.apanal.qlife.sys.model.User;
import com.apanal.qlife.sys.service.ResourceService;

/**
 * 公共控制类
 * 
 * 
 * @author shuliangxing
 * 
 * @date 2015-8-3下午2:43:01
 */
@Controller
public class CommonController {

	@Autowired
	private ResourceService resourceService;

	@Autowired
	private OrganizationService OrganizationService;

	@Autowired
	private SysAnnounceService sysAnnounceService;

	/**
	 * 首页
	 * 
	 * @param loginUser
	 * @param model
	 * @return
	 */
	@RequestMapping("/")
	public String index(@CurrentUser User loginUser, Model model) {
		Resource menus = resourceService.findMenusForLevel(loginUser);
		model.addAttribute("menus", menus);

		return "sys/index";
	}

	/**
	 * 登录页
	 * 
	 * @param req
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/login")
	public String showLoginForm(HttpServletRequest req, Model model) {
		// 如果用户已经登录,转向首页
		Subject sub = SecurityUtils.getSubject();
		if (sub.isAuthenticated() || sub.isRemembered()) {
			return "redirect:/";
		}

		String exceptionClassName = (String) req
				.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
		String error = null;

		if (!StringUtils.isEmpty(exceptionClassName)) {
			// 登录次数缓存,登录错误次数超过规定次数则锁定,原单位秒
			int loginRecordCacheToIdle = Integer.valueOf(PropertieUtil
					.getPropertie("loginRecordCacheToIdleSeconds")) / 60;

			if (UnknownAccountException.class.getName().equals(
					exceptionClassName)) {
				error = "用户名不存在";
			} else if (IncorrectCredentialsException.class.getName().equals(
					exceptionClassName)) {
				error = "密码错误";

				// 用户名
				String username = req.getParameter("username");
				// 缓存管理器
				CacheManager shiroCacheManager = SpringContextHolder
						.getBean("cacheManager");
				// 允许密码错误次数,0表示不限制次数登录
				int allowLoginCount = Integer.valueOf(PropertieUtil
						.getPropertie("allowLoginCount"));

				if (username != null && allowLoginCount > 0) {
					AtomicInteger retryCount = (AtomicInteger) shiroCacheManager
							.getCache("passwordRetryCache").get(username);
					if (retryCount.get() >= allowLoginCount) {
						error += "，请" + loginRecordCacheToIdle + "分钟后重试";
					} else {
						error += "，剩余" + (allowLoginCount - retryCount.get())
								+ "次登录机会";
					}
				}
			} else if (LockedAccountException.class.getName().equals(
					exceptionClassName)) {
				error = Constants.MSG_USER_LOCKED;
			} else if (OrgDisableException.class.getName().equals(
					exceptionClassName)) {
				error = Constants.MSG_ORG_DISABLE;
			} else if (ExcessiveAttemptsException.class.getName().equals(
					exceptionClassName)) {
				error = "错误次数过多，请" + loginRecordCacheToIdle + "分钟后重试";
			} else if ("jCaptcha.mustError".equals(exceptionClassName)) {
				error = "需要验证码";
			} else if ("jCaptcha.error".equals(exceptionClassName)) {
				error = "验证码错误";
			} else {
				// error = "其他错误：" + exceptionClassName;
				error = Constants.DEFAULT_MSG_ERROR;
			}
		} else {
			// 被管理员强制退出
			if (req.getParameter(Constants.URL_FORCE_LOGOUT) != null) {
				error = Constants.MSG_FORCE_LOGOUT;
			}
			// 被管理员强制退出
			else if (req.getParameter(Constants.URL_REPEAT_LOGIN) != null) {
				error = Constants.MSG_REPEAT_LOGIN;
			}
			// 账号被锁
			else if (req.getParameter(Constants.URL_USER_LOCKED) != null) {
				error = Constants.MSG_USER_LOCKED;
			}
			// 账号直属机构停用
			else if (req.getParameter(Constants.URL_ORG_DISABLE) != null) {
				error = Constants.MSG_ORG_DISABLE;
			}
		}

		model.addAttribute("error", error);
		return "sys/login";
	}

	/**
	 * 欢迎页
	 * 
	 * @return
	 */
	@RequestMapping("/welcome")
	public String welcome() {
		return "sys/welcome";
	}

	/**
	 * 帮助页
	 * 
	 * @return
	 */
	@RequestMapping("/help")
	public String help() {
		return "sys/help";
	}

	/**
	 * 忘记密码页
	 * 
	 * @return
	 */
	@RequestMapping("/forgetPwd")
	public String forgetPwd() {
		return "sys/forgetPwd";
	}

	/**
	 * 验证码
	 * 
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/validCaptcha")
	public boolean validCaptcha(HttpServletRequest request, String captcha) {
		if (captcha == null || "".equals(captcha.trim())) {
			return false;
		}
		return JCaptcha.hasCaptcha(request, captcha);
	}

	/**
	 * 根据当前登录用户获取待审核总条数的接口
	 * 
	 * @param user
	 * @return
	 */
	@RequiresPermissions("mycenter:audit:view")
	@RequestMapping("/findMyCountAudit")
	@ResponseBody
	public Integer findMyCountAudit() {
		return OrganizationService.selectCountAudit();
	}

	/**
	 * 首页查询公告列表
	 * 
	 * @param orgId
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "findSysAnnounce", method = RequestMethod.GET)
	@ResponseBody
	public List<Advice> findSysAnnounce(@CurrentUser User loginUser, Page page) {
		Advice advice = new Advice();
		return sysAnnounceService
				.findAonnce(loginUser.getOrgId(), page, advice).getEntityList();
	}

	/**
	 * 首页查询公告详情
	 * 
	 * @param advId
	 * @return
	 */
	@RequestMapping(value = "findSysAnnounceDetail", method = RequestMethod.GET)
	@ResponseBody
	public Advice findSysAnnounceDetail(Long advId) {
		return sysAnnounceService.findSysAnnounceDtail(advId);
	}
}
